package com.kexio.file.controller;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.kexio.auth.annotation.Audit;
import com.kexio.auth.annotation.RequiresPermission;
import com.kexio.common.dto.Result;
import com.kexio.file.entity.FileVersion;
import com.kexio.file.service.FileVersionService;
import com.kexio.file.vo.FileVersionVO;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;

/**
 * 文件版本管理控制器
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
@Tag(name = "文件版本管理", description = "文件版本管理相关接口")
@RestController
@RequestMapping("/file/version")
// 类级可按需启用
public class FileVersionController {

    @Autowired
    private FileVersionService fileVersionService;

    /**
     * 创建新版本
     */
    @Operation(summary = "创建新版本", description = "为指定文件创建新版本")
    @PostMapping("/create")
    @RequiresPermission("file:version:create")
    @Audit(value = "创建文件版本", module = "file")
    public Result<FileVersionVO> createVersion(@RequestBody CreateVersionRequest request) {
        try {
            FileVersion newVersion = fileVersionService.createNewVersion(
                    request.getFileId(),
                    request.getStorageObjectId(),
                    request.getChangeLog(),
                    request.getVersionTags(),
                    request.getSetAsCurrent()
            );
            return Result.success(fileVersionService.convertToVO(newVersion));
        } catch (Exception e) {
            return Result.error("创建版本失败: " + e.getMessage());
        }
    }

    /**
     * 获取文件的所有版本
     */
    @Operation(summary = "获取文件版本列表", description = "获取指定文件的所有版本")
    @GetMapping("/list/{fileId}")
    @RequiresPermission("file:version:list")
    public Result<List<FileVersionVO>> getVersions(
            @Parameter(description = "文件ID") @PathVariable String fileId) {
        try {
            List<FileVersionVO> versions = fileVersionService.getVersionsByFileId(fileId);
            return Result.success(versions);
        } catch (Exception e) {
            return Result.error("获取版本列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取文件当前版本
     */
    @Operation(summary = "获取当前版本", description = "获取指定文件的当前版本")
    @GetMapping("/current/{fileId}")
    @RequiresPermission("file:version:view")
    public Result<FileVersionVO> getCurrentVersion(
            @Parameter(description = "文件ID") @PathVariable String fileId) {
        try {
            FileVersionVO currentVersion = fileVersionService.getCurrentVersion(fileId);
            if (currentVersion == null) {
                return Result.error("文件当前版本不存在");
            }
            return Result.success(currentVersion);
        } catch (Exception e) {
            return Result.error("获取当前版本失败: " + e.getMessage());
        }
    }

    /**
     * 根据版本号获取版本信息
     */
    @Operation(summary = "获取指定版本", description = "根据版本号获取版本信息")
    @GetMapping("/{fileId}/{versionNumber}")
    @RequiresPermission("file:version:view")
    public Result<FileVersionVO> getVersionByNumber(
            @Parameter(description = "文件ID") @PathVariable String fileId,
            @Parameter(description = "版本号") @PathVariable Integer versionNumber) {
        try {
            FileVersionVO version = fileVersionService.getVersionByNumber(fileId, versionNumber);
            if (version == null) {
                return Result.error("版本不存在");
            }
            return Result.success(version);
        } catch (Exception e) {
            return Result.error("获取版本信息失败: " + e.getMessage());
        }
    }

    /**
     * 切换到指定版本
     */
    @Operation(summary = "切换版本", description = "将指定版本设为当前版本")
    @PutMapping("/switch")
    @RequiresPermission("file:version:switch")
    @Audit(value = "切换文件版本", module = "file")
    public Result<Void> switchToVersion(@RequestBody SwitchVersionRequest request) {
        try {
            boolean success = fileVersionService.switchToVersion(request.getFileId(), request.getVersionId());
            if (success) {
                return Result.success();
            } else {
                return Result.error("切换版本失败");
            }
        } catch (Exception e) {
            return Result.error("切换版本失败: " + e.getMessage());
        }
    }

    /**
     * 回滚到指定版本
     */
    @Operation(summary = "回滚版本", description = "回滚到指定版本并创建新版本")
    @PostMapping("/rollback")
    @RequiresPermission("file:version:rollback")
    @Audit(value = "回滚文件版本", module = "file")
    public Result<FileVersionVO> rollbackToVersion(@RequestBody RollbackVersionRequest request) {
        try {
            FileVersion newVersion = fileVersionService.rollbackToVersion(
                    request.getFileId(),
                    request.getVersionNumber(),
                    request.getChangeLog()
            );
            return Result.success(fileVersionService.convertToVO(newVersion));
        } catch (Exception e) {
            return Result.error("回滚版本失败: " + e.getMessage());
        }
    }

    /**
     * 删除指定版本
     */
    @Operation(summary = "删除版本", description = "删除指定版本（软删除）")
    @DeleteMapping("/{versionId}")
    @RequiresPermission("file:version:delete")
    @Audit(value = "删除文件版本", module = "file")
    public Result<Void> deleteVersion(
            @Parameter(description = "版本ID") @PathVariable String versionId,
            @Parameter(description = "是否强制删除") @RequestParam(defaultValue = "false") Boolean force) {
        try {
            boolean success = fileVersionService.deleteVersion(versionId, force);
            if (success) {
                return Result.success();
            } else {
                return Result.error("删除版本失败");
            }
        } catch (Exception e) {
            return Result.error("删除版本失败: " + e.getMessage());
        }
    }

    /**
     * 删除文件的所有版本
     */
    @Operation(summary = "删除所有版本", description = "删除指定文件的所有版本")
    @DeleteMapping("/all/{fileId}")
    @RequiresPermission("file:version:delete")
    @Audit(value = "删除文件所有版本", module = "file")
    public Result<Void> deleteAllVersions(
            @Parameter(description = "文件ID") @PathVariable String fileId) {
        try {
            boolean success = fileVersionService.deleteAllVersions(fileId);
            if (success) {
                return Result.success();
            } else {
                return Result.error("删除所有版本失败");
            }
        } catch (Exception e) {
            return Result.error("删除所有版本失败: " + e.getMessage());
        }
    }

    /**
     * 版本对比
     */
    @Operation(summary = "版本对比", description = "对比两个版本的差异")
    @GetMapping("/compare/{fileId}")
    @RequiresPermission("file:version:compare")
    public Result<String> compareVersions(
            @Parameter(description = "文件ID") @PathVariable String fileId,
            @Parameter(description = "源版本号") @RequestParam Integer fromVersion,
            @Parameter(description = "目标版本号") @RequestParam Integer toVersion) {
        try {
            String diffInfo = fileVersionService.compareVersions(fileId, fromVersion, toVersion);
            return Result.success(diffInfo);
        } catch (Exception e) {
            return Result.error("版本对比失败: " + e.getMessage());
        }
    }

    /**
     * 统计版本数量
     */
    @Operation(summary = "统计版本数量", description = "统计指定文件的版本数量")
    @GetMapping("/count/{fileId}")
    @RequiresPermission("file:version:view")
    public Result<Integer> countVersions(
            @Parameter(description = "文件ID") @PathVariable String fileId) {
        try {
            int count = fileVersionService.countVersions(fileId);
            return Result.success(count);
        } catch (Exception e) {
            return Result.error("统计版本数量失败: " + e.getMessage());
        }
    }

    /**
     * 批量统计版本数量
     */
    @Operation(summary = "批量统计版本数量", description = "批量统计多个文件的版本数量")
    @PostMapping("/batch-count")
    @RequiresPermission("file:version:view")
    public Result<Map<String, Integer>> batchCountVersions(@RequestBody List<String> fileIds) {
        try {
            Map<String, Integer> counts = fileVersionService.batchCountVersions(fileIds);
            return Result.success(counts);
        } catch (Exception e) {
            return Result.error("批量统计版本数量失败: " + e.getMessage());
        }
    }

    /**
     * 清理历史版本
     */
    @Operation(summary = "清理历史版本", description = "清理指定文件的历史版本，保留最近N个版本")
    @PostMapping("/cleanup/{fileId}")
    @RequiresPermission("file:version:cleanup")
    @Audit(value = "清理文件历史版本", module = "file")
    public Result<Integer> cleanupHistoryVersions(
            @Parameter(description = "文件ID") @PathVariable String fileId,
            @Parameter(description = "保留版本数量") @RequestParam Integer keepCount) {
        try {
            int cleanedCount = fileVersionService.cleanupHistoryVersions(fileId, keepCount);
            return Result.success(cleanedCount);
        } catch (Exception e) {
            return Result.error("清理历史版本失败: " + e.getMessage());
        }
    }

    // ==================== 内部类 ====================

    /**
     * 创建版本请求
     */
    public static class CreateVersionRequest {
        private String fileId;
        private String storageObjectId;
        private String changeLog;
        private String versionTags;
        private Boolean setAsCurrent;

        // Getters and Setters
        public String getFileId() { return fileId; }
        public void setFileId(String fileId) { this.fileId = fileId; }
        public String getStorageObjectId() { return storageObjectId; }
        public void setStorageObjectId(String storageObjectId) { this.storageObjectId = storageObjectId; }
        public String getChangeLog() { return changeLog; }
        public void setChangeLog(String changeLog) { this.changeLog = changeLog; }
        public String getVersionTags() { return versionTags; }
        public void setVersionTags(String versionTags) { this.versionTags = versionTags; }
        public Boolean getSetAsCurrent() { return setAsCurrent; }
        public void setSetAsCurrent(Boolean setAsCurrent) { this.setAsCurrent = setAsCurrent; }
    }

    /**
     * 切换版本请求
     */
    public static class SwitchVersionRequest {
        private String fileId;
        private String versionId;

        // Getters and Setters
        public String getFileId() { return fileId; }
        public void setFileId(String fileId) { this.fileId = fileId; }
        public String getVersionId() { return versionId; }
        public void setVersionId(String versionId) { this.versionId = versionId; }
    }

    /**
     * 回滚版本请求
     */
    public static class RollbackVersionRequest {
        private String fileId;
        private Integer versionNumber;
        private String changeLog;

        // Getters and Setters
        public String getFileId() { return fileId; }
        public void setFileId(String fileId) { this.fileId = fileId; }
        public Integer getVersionNumber() { return versionNumber; }
        public void setVersionNumber(Integer versionNumber) { this.versionNumber = versionNumber; }
        public String getChangeLog() { return changeLog; }
        public void setChangeLog(String changeLog) { this.changeLog = changeLog; }
    }
}
